/*====================================================================================================*/
/*====================================================================================================*/
#include "stm32f4_system.h"
#include "stm32f4_flash.h"
#include "stm32f4_iap.h"
#include "experiment_stm32f4.h"
#include "module_rs232.h"
/*====================================================================================================*/
/*====================================================================================================*/
static u8 RecvBuf[4096] = {0};
/*====================================================================================================*/
/*====================================================================================================*
**函數 : IAP_Init
**功能 : IAP 初始化
**輸入 : None
**輸出 : None
**使用 : IAP_Init();
**====================================================================================================*/
/*====================================================================================================*/
void IAP_Init( void )
{
  RS232_Config();
}
/*====================================================================================================*/
/*====================================================================================================*
**函數 : IAP_Download
**功能 : IAP Download Binary Code
**輸入 : None
**輸出 : None
**使用 : IAP_Download();
**====================================================================================================*/
/*====================================================================================================*/
#define RecvCodeSize 4096
void IAP_Download( void )
{
  u32 WriteAddr = 0;
  u32 CodeSize = 0;
  u32 tmpCodeSize = 0;

  u8 FileInfo[4] = {0};

  LED_G = 0;
  RS232_RecvData((u8*)FileInfo, 4);
  CodeSize = (FileInfo[0]<<24) | (FileInfo[1]<<16) | (FileInfo[2]<<8) | (FileInfo[3]);

  RS232_SendData((u8*)FileInfo, 4);
  RS232_RecvData((u8*)FileInfo, 1);
  tmpCodeSize = CodeSize;

  if(FileInfo[0] == 0xF0) {
    // Download BinaryFile
    while(tmpCodeSize) {
      LED_G = !LED_G;
      if(tmpCodeSize>=RecvCodeSize) {
        RS232_RecvData(RecvBuf+WriteAddr, RecvCodeSize);
        RS232_SendData(RecvBuf+WriteAddr, RecvCodeSize);
        WriteAddr += RecvCodeSize;
        tmpCodeSize -= RecvCodeSize;
      }
      else {
        RS232_RecvData(RecvBuf+WriteAddr, tmpCodeSize);
        RS232_SendData(RecvBuf+WriteAddr, tmpCodeSize);
        tmpCodeSize = 0;
      }
    }

    IAP_UpdateApp(RecvBuf, CodeSize);
  }
  else {
    LED_R = 0;
  }
}
/*====================================================================================================*/
/*====================================================================================================*
**函數 : IAP_UpdateApp
**功能 : IAP Update App
**輸入 : None
**輸出 : None
**使用 : IAP_UpdateApp(BinaryCode, CodeSize);
**====================================================================================================*/
/*====================================================================================================*/
#define UpdateSize 4096
void IAP_UpdateApp( u8* BinaryCode, uc32 CodeSize )
{
  u32 WriteAddr = 0;
  u32 tmpSize = CodeSize;

  Flash_EraseSectors(IAP_APP_ADDR, IAP_APP_ADDR + CodeSize);

  while(tmpSize) {
    if(tmpSize >= UpdateSize) {
      Flash_WriteDataU8(IAP_APP_ADDR + WriteAddr, BinaryCode + WriteAddr, UpdateSize);
      WriteAddr += UpdateSize;
      tmpSize -= UpdateSize;
    }
    else {
      Flash_WriteDataU8(IAP_APP_ADDR + WriteAddr, BinaryCode + WriteAddr, tmpSize);
      tmpSize = 0;
    }
  }
}
/*====================================================================================================*/
/*====================================================================================================*
**函數 : IAP_JumpToApp
**功能 : 執行載入程式
**輸入 : None
**輸出 : None
**使用 : IAP_JumpToApp();
**====================================================================================================*/
/*====================================================================================================*/
void IAP_JumpToApp( void )
{
  u32 JumpAddr;
  void (*JumpToApp)(void);

  JumpAddr = *(vu32*)(IAP_APP_ADDR + 4);
  JumpToApp = (void (*)(void))JumpAddr;
  __set_MSP(*(vu32*)IAP_APP_ADDR);
  JumpToApp();
}
/*====================================================================================================*/
/*====================================================================================================*
**函數 : IAP_SetVectorTable
**功能 : 重新設定向量表
**輸入 : Offset
**輸出 : None
**使用 : IAP_SetVectorTable(IAP_FLASH_SIZE);
**====================================================================================================*/
/*====================================================================================================*/
//void IAP_SetVectorTable( u32 Offset )
//{
//  SCB->VTOR = (u32)(IAP_BOOT_ADDR | (Offset & (u32)0x1FFFFF80));
//}
/*====================================================================================================*/
/*====================================================================================================*/
